package com.yuandian.management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuandian.api.customer_perception.po.SystemOverviewParams;
import com.yuandian.api.management.entity.ConfArea;
import com.yuandian.api.management.vo.AreaDataVo;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.bpm.common.security.util.SecurityUtils;
import com.yuandian.management.mapper.ConfAreaMapper;
import com.yuandian.management.service.ConfAreaService;
import com.yuandian.management.vo.RegionMappingExcelVo;
import com.yuandian.management.vo.RegionMappingInfo;
import com.yuandian.management.vo.RegionMappingVo;
import com.yuandian.management.vo.SearchOptionVo;
import com.yuandian.utils.poi.BatchDataResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 区域表-Service实现
 * @author zfsn
 * @date 2023-3-28
 */
@Service
public class ConfAreaServiceImpl extends ServiceImpl<ConfAreaMapper, ConfArea>
		implements ConfAreaService {

	@Autowired
	ConfAreaMapper confAreaMapper;
	/**
	 * 新增数据
	 *
	 * @param confArea 实例对象
	 * @return 通用返回对象
	 */
	@Override
	public R<String> saveConfArea(RegionMappingInfo confArea) {
		if(confAreaMapper.add(confArea, SecurityUtils.getUser().getName()) == 0){
			return R.failed("区域编码"+confArea.getCode()+"已存在!");
		}
		return R.ok();
	}

	/**
	 * 通过主键更新数据
	 *
	 * @param mappingInfo 实例对象
	 * @return 通用返回对象
	 */
	@Override
	public R<String> updateConfAreaById(RegionMappingInfo mappingInfo) {
		RegionMappingInfo regionMappingInfo = confAreaMapper.queryById(mappingInfo.getId());
		if (regionMappingInfo == null){
			return R.failed("id不存在");
		}
		if (regionMappingInfo.getCode().equals(mappingInfo.getCode())){
			confAreaMapper.updateData(mappingInfo, SecurityUtils.getUser().getName());
		}else {
			List<RegionMappingInfo> regionMappingInfos = confAreaMapper.queryNameAndAreaIdAll();
			for (RegionMappingInfo regionMappingInfo1 : regionMappingInfos) {
				if (regionMappingInfo1.getCode().equals(mappingInfo.getCode())){
					return R.failed("区域编码"+regionMappingInfo1.getCode()+"已存在!");
				}
			}
			confAreaMapper.updateData(mappingInfo, SecurityUtils.getUser().getName());
		}
		return R.ok();
	}

	/**
	 * 分页查询
	 *
	 * @param regionMappingVo 筛选条件
	 * @return 通用返回对象
	 */
	@Override
	public Page<RegionMappingVo> listPage(RegionMappingVo regionMappingVo) {
		Page<RegionMappingVo> confAreaPage = confAreaMapper.listPage(new Page<>(regionMappingVo.getPageNum(), regionMappingVo.getPageSize()), regionMappingVo);
		List<RegionMappingVo> list = confAreaPage.getRecords();
		list.forEach(s -> s.setFullRegionName(Objects.equals(s.getProvince(), s.getCity())?  s.getProvince() : s.getProvince() + s.getCity()) );
		list.forEach(s->{
			if (s.getType()==5){
				s.setRegionName(s.getCity());
			}
		});

		return confAreaPage;
	}

	/**
	 * 获取省份信息
	 *
	 * @return 通用返回对象
	 */
	@Override
	public R<List<Map<String, String>>> getProvince() {
		return R.ok(confAreaMapper.getProvince());
	}

	/**
	 * 通过code获取区域信息
	 *
	 * @param code
	 * @return 通用返回对象
	 */
	@Override
	public R<List<Map<String, String>>> getCity(String code) {
		return R.ok(confAreaMapper.getCity(code));
	}

	/**
	 * 获取所有区域信息
	 *
	 * @return 通用返回对象
	 */
	@Override
	public List<Map<String, String>> getAreaCodeAndName() {
		return confAreaMapper.getAreaCodeAndName();
	}

	/**
	 * 根据区域拼音查询子集信息
	 * @return 通用返回对象
	 */
	@Override
	public List<AreaDataVo> queryCodeByParentName(String areaName) {
		return confAreaMapper.queryCodeByParentName(areaName);
	}

	@Override
	public List<RegionMappingInfo> queryDataByIds(Integer idList) {
		return confAreaMapper.queryDataByIds(idList);
	}

	@Override
	public R<String> removeDataByIds(List<Integer> ids) {
		 confAreaMapper.removeDataByIds(ids);
		return R.ok();
	}

	/**
	 * 根据code获取区域名称
	 * @param areaCode
	 * @return
	 */
	@Override
	public R<String> queryAreaName(String areaCode) {
		String areaName = this.lambdaQuery().eq(ConfArea::getCode, areaCode).last("limit 1").one().getName();
		return  R.ok(areaName);
	}

	/**
	 * 查询地市id和名称
	 * @param params 请求参数
	 * @return 查询地市id和名称
	 */
	@Override
	public List<SearchOptionVo> queryAreaCodeAndName(SystemOverviewParams params) {
		return this.baseMapper.queryAreaCodeAndName(params);
	}


	/**
	 * 判断区域编码是否重复
	 * @param confArea
	 * @return
	 */
	private boolean checkAreaCodeDuplicates(ConfArea confArea){
		QueryWrapper<ConfArea> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("code", confArea.getCode());
		if (confArea.getId() != null){
			queryWrapper.ne("id", confArea.getId());
		}
		return super.count(queryWrapper) > 0;
	}

	/**
	 * 保存导入的数据
	 *
	 * @param dataList
	 */
	@Override
	public void saveBatchExcelData(List<RegionMappingExcelVo> dataList) {
		if(!CollectionUtils.isEmpty(dataList)) {
			Set<RegionMappingInfo> set = new HashSet<>();

			for (RegionMappingExcelVo excelVo : dataList) {
				RegionMappingInfo info = new RegionMappingInfo();
				info.setAreaId(excelVo.getId());
				info.setCode(excelVo.getRegionCode());
				set.add(info);
			}
			confAreaMapper.addAll(set, SecurityUtils.getUser().getName());
		}
	}

	/**
	 * 入库前-批量校验数据
	 *
	 * @param dataList
	 * @return
	 */
	@Override
	public BatchDataResult<RegionMappingExcelVo> checkBatchExcelData(List<RegionMappingExcelVo> dataList) {
		List<RegionMappingExcelVo> successList = new ArrayList<>();
		List<RegionMappingExcelVo> failList = new ArrayList<>();

		if(!CollectionUtils.isEmpty(dataList)) {

			List<ConfArea> areaAll = confAreaMapper.queryAreaAll();
			Map<String, ConfArea> areaMap = areaAll.stream().collect(Collectors.toMap(ConfArea::getFullRegionName, Function.identity()));

			List<String> regionCodeList = dataList.stream().map(RegionMappingExcelVo::getRegionCode).distinct().collect(Collectors.toList());
			List<String> existRegionCodes = confAreaMapper.getExistRegionCodes(regionCodeList);

			for (RegionMappingExcelVo excelVo : dataList) {
				if (!existRegionCodes.contains(excelVo.getRegionCode()) && null != areaMap.get(excelVo.getParentAreaName() + excelVo.getRegionName())) {
					excelVo.setId(areaMap.get(excelVo.getParentAreaName() + excelVo.getRegionName()).getId());
					successList.add(excelVo);
				} else {
					failList.add(excelVo);
				}
			}
		}

		return new BatchDataResult<>(true, successList, failList);
	}

	/**
	 * 解析阶段-校验数据
	 *
	 * @param data
	 * @return
	 */
	@Override
	public boolean checkExcelData(RegionMappingExcelVo data) {
		try {
			Field[] fields = data.getClass().getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				if (field.get(data) == null) {
					return false;
				}
			}
		} catch (IllegalAccessException e) {
			log.error(e.getMessage(), e);
			return false;
		}

		if (confAreaMapper.checkAreaData(data) != null) {
			return true;
		}

		return false;
	}
}
